<template>
  <el-dialog draggable v-model="dialogVisible" title="标记为 Swagger" width="500">
    <el-form ref="formRef" :model="formState" label-width="45px">
      <el-form-item label="title" prop="title" :rules="titleRules">
        <el-input
          clearable
          v-model="formState.title"
          type="text"
          autocomplete="off"
          maxlength="15"
        />
      </el-form-item>
      <el-form-item label="href" prop="url" :rules="docsApiRules">
        <el-input clearable v-model="formState.url" type="text" autocomplete="off" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">保存</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script lang="ts">
import type { FormItemRule } from 'element-plus'
import { storageStore } from '@shared/context'
import axios from 'axios'
import { defineComponent, reactive, ref } from 'vue'
import { onMessage } from '@shared/clientMessage'
import { ContextMenuId, PostMessageType } from '@shared/types'

export default defineComponent({
  name: 'SwaggerForm',
  setup() {
    const formRef = ref()

    const dialogVisible = ref(false)

    const formState = reactive({
      title: '',
      url: ''
    })

    const titleRules: FormItemRule[] = [{ required: true, message: '请输入标题' }]

    const docsApiRules: FormItemRule[] = [
      { required: true, type: 'url', message: '请输入有效的地址' },
      {
        validator(rule, value: string, cb) {
          const item = storageStore.docsApis.find(({ origin }) => value.includes(origin))
          if (item) {
            cb(new Error(`域名 ${item.origin} 已存在，请勿重复添加`))
          } else {
            axios.get(value).then(({ data }) => {
              if (data.openapi) cb()
              else cb(new Error('该地址无法获取 swagger 对象数据'))
            }, cb)
          }
        }
      }
    ]

    function onSubmit() {
      formRef.value?.validate((valid: boolean) => {
        if (valid) {
          const { title, url } = formState
          const { origin, pathname } = new URL(url)
          storageStore.docsApis.push({ title, origin, pathname })
          formRef.value?.resetFields()

          location.reload()
        }
      })
    }

    onMessage(PostMessageType.CONTEXT_MENU, (menuId: ContextMenuId) => {
      if (menuId !== ContextMenuId.MARKE_AS_SWAGGER) return
      Object.assign(formState, { title: document.title, url: `${location.origin}/v3/api-docs` })

      dialogVisible.value = true
    })

    return { storageStore, formRef, dialogVisible, formState, titleRules, docsApiRules, onSubmit }
  }
})
</script>
